#ifndef _THREAD_H_
#define _THREAD_H_

#include <pthread.h>
#include <event.h>

#include "conn.h"
#include "list.h"

#define LOG_BUFFER_SIZE		1024

enum TH_TYPE {
	TYPE_WORKER = 0, 
	TYPE_MASTER = 1, 
	TYPE_LOGGER	= 2,
	TYPE_TIMER	= 3,
};

extern const char * TH_TAG[];
#define TTAG(p)				TH_TAG[(p)->type]

void threads_wait(int count);

typedef struct TASK {
	struct list_head list;
	void *data;
} TASK;

struct THREAD;
typedef int (* TH_ONTASK_FUNC)(TASK * task, const struct THREAD * me);
typedef int (* TH_INIT_FUNC)(const struct THREAD * me);
typedef int (* TH_CLEAR_FUNC)(const struct THREAD * me);

typedef struct THREAD {
	pthread_t			tid;			/* unique ID of this thread */
	int					type;			/* thread's type */
	int					running;		/* thread is running ? */
	struct event_base	*base;			/* event base point to handle.base */
	struct event		request_event;	/* listen event for request pipe */
	struct event		response_event;	/* listen event for response pipe */
	int					request_send_fd;	/* sending end of notify pipe */
	int					request_recv_fd;	/* receiving end of notify pipe */
	int					response_send_fd;	/* sending end of notify pipe */
	int					response_recv_fd;	/* receiving end of notify pipe */
	struct list_head	request_q;		/* request queue */
	struct list_head	response_q;		/* response queue */
	pthread_mutex_t		request_lock;	/* mutex master and worker on request */
	pthread_mutex_t		response_lock;	/* mutex master and worker on response */
	void * sys;							/* master->srv, logger->logging, timer->timing */
	void * user;						/* user can save data here */
	TH_ONTASK_FUNC		ontask;			/* ontask function pointer */
	TH_INIT_FUNC		init;			/* init function pointer */
	TH_CLEAR_FUNC		clear;			/* clear function pointer */
} THREAD;

THREAD * thread_new(TH_ONTASK_FUNC ontask, TH_INIT_FUNC init,
						TH_CLEAR_FUNC clear, void * sys);
int thread_free(THREAD * p);
int thread_startup(THREAD * p);
int thread_shutdown(THREAD * p);

/* -- send request to worker -- */
int send_request(TASK * task, THREAD * p);
/* -- worker recv request -- */
TASK * recv_request(THREAD * p);
/* -- send response to master -- */
int send_response(TASK * task, THREAD * p);
/* -- master recv response -- */
TASK * recv_response(THREAD * p);

#endif
